package cn.net.cfss.fgbp.face.console.controller;

import cn.net.cfss.fgbp.api.console.constant.YesOrNoEnum;
import cn.net.cfss.fgbp.api.console.dto.SysUserDto;
import cn.net.cfss.fgbp.api.console.dto.SysUserRoleDto;
import cn.net.cfss.fgbp.api.console.inte.ISysOrganService;
import cn.net.cfss.fgbp.api.console.inte.ISysUserService;
import cn.net.cfss.fgbp.api.console.vo.SysOrganVo;
import cn.net.cfss.fgbp.api.console.vo.SysUserVo;
import cn.net.cfss.fgbp.base.common.GlobalConstants;
import cn.net.cfss.fgbp.base.controller.BaseController;
import cn.net.cfss.fgbp.base.page.PageData;
import cn.net.cfss.fgbp.face.console.service.OperationService;
import cn.net.cfss.fgbp.face.console.util.ReturnUtil;
import cn.net.cfss.fgbp.face.console.vo.BaseParas;
import cn.net.cfss.fgbp.spi.manage.constant.OperationTypeEnum;
import cn.net.cfss.fgbp.spi.manage.constant.TableNameConstant;
import cn.net.cfss.fgbp.spi.manage.dto.FscTenantDto;
import cn.net.cfss.fgbp.spi.manage.dto.FscTenantUserDto;
import cn.net.cfss.fgbp.spi.manage.inte.IFscTenantUserService;
import cn.net.cfss.fgbp.spi.manage.vo.FscTenantUserVo;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("console/user")
public class SysUserController extends BaseController {

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    public ISysOrganService departmentService;

    @Autowired
    private IFscTenantUserService fscTenantUserService;

    @Value("${application.resource.servProAdmin:serviceprovider_admin}")
    private String serAdmin;

    @Value("${application.resource.superAdmin:super_admin}")
    private String supAdmin;

    @Value("${application.resource.serviceProvider:1}")
    private Long serviceProvider;

    @Value("${application.resource.serviceProviderName:银雁科技服务集团股份有限公司}")
    private String serviceProviderName;

    @Autowired
    private OperationService operationService;

    @ApiOperation("用户新增")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addUserRole(@RequestBody BaseParas paras) {
        SysUserVo vo = JSONObject.toJavaObject(paras.getPlain(), SysUserVo.class);
        if(!this.uniqueUserEmail(vo)){
            return ReturnUtil.returnErr("邮箱已已绑定用户");
        }
        if(!this.uniqueUserPhone(vo)){
            return ReturnUtil.returnErr("手机号码已绑定用户");
        }
        if (sysUserService.uniquenessCheck(vo.getUsername(), vo.getId())) {
            vo.setCreateBy(Long.parseLong(request.getHeader(GlobalConstants.HEADER_USERID)));
            //不是内部用户 设置默认关联机构
            if (YesOrNoEnum.NO.equals(vo.getIsInternalStaff())){
                vo.setServiceProvider(serviceProvider);
                vo.setServiceProviderName(serviceProviderName);
            }else {
                //查询机构名称放进去
                if(null != vo.getServiceProvider()){
                    SysOrganVo sysOrganVo = departmentService.detail(vo.getServiceProvider());
                    vo.setServiceProviderName(sysOrganVo.getName());
                }
            }

            SysUserDto sysUserDto = sysUserService.addUserRole(vo);
            //绑定租户
            if (vo.getTenantId() != null) {
                FscTenantUserDto fscTenantUserDto = new FscTenantUserDto();
                fscTenantUserDto.setUserId(sysUserDto.getId());
                fscTenantUserDto.setTenantId(vo.getTenantId());
                fscTenantUserService.addOrUpdate(fscTenantUserDto);
            }

            //记录操作日志
            JSONObject newData = new JSONObject();
            newData.put(TableNameConstant.T_SYS_USER, sysUserDto);
            SysUserRoleDto sysUserRoleDto = new SysUserRoleDto();
            sysUserRoleDto.setUserId(sysUserDto.getId());
            List<SysUserRoleDto> sysUserRoleDtos = sysUserService.queryUserRole(sysUserRoleDto);
            newData.put(TableNameConstant.T_SYS_USER_ROLE, sysUserRoleDtos);
            String opRemark = "新增用户";
            operationService.addOperationLog(OperationTypeEnum.ADD, opRemark, null, newData.toJSONString());
            return ReturnUtil.returnSucc();
        }
        return ReturnUtil.returnErr("用户名已存在");

    }

    @ApiOperation("用户修改")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public String editUserRole(@RequestBody BaseParas paras) {
        SysUserVo vo = JSONObject.toJavaObject(paras.getPlain(), SysUserVo.class);
        if(!this.uniqueUserEmail(vo)){
            return ReturnUtil.returnErr("邮箱已已绑定用户");
        }
        if(!this.uniqueUserPhone(vo)){
            return ReturnUtil.returnErr("手机号码已绑定用户");
        }
        //获取用户关联机构名称
        SysOrganVo sysOrganVo = departmentService.detail(vo.getServiceProvider());
        if(null == sysOrganVo){
            return ReturnUtil.returnErr("请选择关联机构!");
        }

        JSONObject oldData = new JSONObject();
        SysUserVo sysUserVo = sysUserService.get(vo.getId());
        SysUserDto sysUserDto = new SysUserDto();
        BeanUtils.copyProperties(sysOrganVo, sysUserDto);
        oldData.put(TableNameConstant.T_SYS_USER, sysUserDto);
        SysUserRoleDto sysUserRoleDto = new SysUserRoleDto();
        sysUserRoleDto.setUserId(sysUserDto.getId());
        List<SysUserRoleDto> sysUserRoleDtos = sysUserService.queryUserRole(sysUserRoleDto);
        oldData.put(TableNameConstant.T_SYS_USER_ROLE, sysUserRoleDtos);

        vo.setServiceProviderName(sysOrganVo.getName());
        //校验用户唯一
        if (sysUserService.uniquenessCheck(vo.getUsername(), vo.getId())) {
            vo.setUpdateBy(Long.parseLong(request.getHeader(GlobalConstants.HEADER_USERID)));
            sysUserService.editUserRole(vo);
            //更新所属租户
            if (vo.getTenantId() != null) {
                FscTenantUserDto fscTenantUserDto = new FscTenantUserDto();
                fscTenantUserDto.setUserId(vo.getId());
                fscTenantUserDto.setTenantId(vo.getTenantId());
                fscTenantUserService.addOrUpdate(fscTenantUserDto);
            } else {
                fscTenantUserService.deleteByUserId(vo.getId());
            }


            //记录操作日志
            String opRemark = "修改用户";
            JSONObject newData = new JSONObject();
            sysUserVo = sysUserService.get(vo.getId());
            BeanUtils.copyProperties(sysOrganVo, sysUserDto);
            newData.put(TableNameConstant.T_SYS_USER, sysUserDto);
            sysUserRoleDto.setUserId(sysUserDto.getId());
            sysUserRoleDtos = sysUserService.queryUserRole(sysUserRoleDto);
            newData.put(TableNameConstant.T_SYS_USER_ROLE, sysUserRoleDtos);
            operationService.addOperationLog(OperationTypeEnum.UPDATE, opRemark, oldData.toJSONString(), newData.toJSONString());

            return ReturnUtil.returnSucc();
        }
        return ReturnUtil.returnErr("用户名已存在");
    }

    @ApiOperation("用户锁定")
    @RequestMapping(value = "/lock/{userId}", method = RequestMethod.GET)
    public String lock(@PathVariable Long userId) {
        sysUserService.lockUser(userId);
        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户解锁")
    @RequestMapping(value = "/unlock/{userId}", method = RequestMethod.GET)
    public String unlock(@PathVariable Long userId) {
        sysUserService.unlockUser(userId);
        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户密码修改")
    @RequestMapping(value = "/update/pwd", method = RequestMethod.POST)
    public String updatePwd(@RequestBody BaseParas paras) {
        SysUserVo vo = JSONObject.toJavaObject(paras.getPlain(), SysUserVo.class);
        sysUserService.updatePwd(vo);
        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户角色设置")
    @RequestMapping(value = "/set/role", method = RequestMethod.POST)
    public String setRole(@RequestBody BaseParas paras) {
        SysUserVo vo = JSONObject.toJavaObject(paras.getPlain(), SysUserVo.class);
        sysUserService.setRole(vo);
        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户业务类型设置")
    @RequestMapping(value = "/set/busiType", method = RequestMethod.POST)
    public String setbusiType(@RequestBody BaseParas paras) {
        SysUserVo vo = JSONObject.toJavaObject(paras.getPlain(), SysUserVo.class);
        sysUserService.setBusiType(vo);
        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户删除")
    @RequestMapping(value = "/delete/{userId}", method = RequestMethod.GET)
    public String delete(@PathVariable Long userId) {
        JSONObject oldData = new JSONObject();
        SysUserVo sysUserVo = sysUserService.get(userId);
        if (sysUserVo != null) {
            SysUserDto sysUserDto = new SysUserDto();
            BeanUtils.copyProperties(sysUserVo, sysUserDto);
            oldData.put(TableNameConstant.T_SYS_USER, sysUserDto);
        }

        sysUserService.delete(userId);

        String opRemark = "删除用户";
        operationService.addOperationLog(OperationTypeEnum.DELETE, opRemark, oldData.toJSONString(), null);

        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户批量删除")
    @RequestMapping(value = "/deleteBatch", method = RequestMethod.POST)
    public String deleteBatch(@RequestBody BaseParas paras) {
        JSONArray jsonArray = paras.getPlain().getJSONArray("userIds");
        List<Long> userIds = JSONObject.parseArray(jsonArray.toJSONString(), Long.class);
        sysUserService.deleteBatchByLogic(userIds);
        return ReturnUtil.returnSucc();
    }

    @ApiOperation("用户详情查询")
    @RequestMapping(value = "/get/{userId}", method = RequestMethod.GET)
    public String get(@PathVariable Long userId) {
        SysUserVo sysUserVo = sysUserService.get(userId);
        Long id = sysUserVo.getId();
        FscTenantUserVo fscTenantUserVo = fscTenantUserService.queryByUserid(id);
        if (fscTenantUserVo != null) {
            sysUserVo.setTenantId(fscTenantUserVo.getTenantId());
            sysUserVo.setTenantName(fscTenantUserVo.getTenantName());
        }
        return ReturnUtil.returnSucc(sysUserVo);
    }

    @ApiOperation("用户分页查询")
    @RequestMapping(value = "/query/page", method = RequestMethod.POST)
    public String queryPage(@RequestBody BaseParas paras) {
        SysUserVo search = JSONObject.toJavaObject(paras.getPlain().getJSONObject("search"), SysUserVo.class);

        //用户权限
        if(sysUserService.checkUserRole(supAdmin, getUserId())){
            //超级管理员看多有
        }else if(sysUserService.checkUserRole(serAdmin, getUserId())){
            //服务商管理员看自己服务商用户
            search.setServiceProvider(getUserSpId());
        }else{
            //看自己
            search.setCreateBy(getUserId());
        }
        PageData<SysUserVo> pageData = PageData.createPagerData(paras.getPlain().getIntValue("pageSize"),
                paras.getPlain().getIntValue("pageNum"), search);
        pageData = sysUserService.queryByPage(pageData);

        List<SysUserVo> rows = pageData.getRows();
        if (rows != null && rows.size() > 0) {
            List<Long> userIds = rows.stream().map(SysUserVo::getId).collect(Collectors.toList());
            Map<Long, FscTenantDto> longStringMap = fscTenantUserService.queryTenantByUserIds(userIds);
            for (SysUserVo row : rows) {
                FscTenantDto fscTenantDto = longStringMap.get(row.getId());
                if (fscTenantDto != null) {
                    row.setTenantName(fscTenantDto.getTenantName());
                    row.setTenantId(fscTenantDto.getId());
                }
            }
        }


        return ReturnUtil.returnSucc(pageData, pageData.getRows());
    }

    /**
     * 不带权限过滤
     * @param paras
     * @return
     */
    @ApiOperation("用户分页查询")
    @RequestMapping(value = "/query/user", method = RequestMethod.POST)
    public String queryUser(@RequestBody BaseParas paras) {
        SysUserVo search = JSONObject.toJavaObject(paras.getPlain().getJSONObject("search"), SysUserVo.class);

        PageData<SysUserVo> pageData = PageData.createPagerData(paras.getPlain().getIntValue("pageSize"),
                paras.getPlain().getIntValue("pageNum"), search);
        pageData = sysUserService.queryByPage(pageData);
        return ReturnUtil.returnSucc(pageData, pageData.getRows());
    }

    @ApiOperation("用户的唯一性校验")
    @RequestMapping(value = "/uniquenessCheck", method = RequestMethod.POST)
    public String uniquenessCheck(@RequestBody BaseParas paras) {
        try {
            String username = paras.getPlain().getString("code");
            Long id = paras.getPlain().getLong("id");
            return ReturnUtil.returnSucc(sysUserService.uniquenessCheck(username, id));
        } catch (Exception e) {
            log.error("用户唯一校验请求失败！", e.getMessage());
            return ReturnUtil.returnErr("用户唯一校验请求失败！");
        }

    }

    @ApiOperation("获取用户的权限信息")
    @RequestMapping(value = "/getPermissions", method = RequestMethod.POST)
    public String getPermissions() {
        String userId = request.getHeader(GlobalConstants.HEADER_USERID);
        return ReturnUtil.returnSucc(sysUserService.getPermissions(userId));
    }

    /**
     * 用户的唯一性检验（邮箱）
     * @param vo
     * @return
     */
    private Boolean uniqueUserEmail(SysUserVo vo){
        SysUserVo userVo =new SysUserVo();
        userVo.setId(vo.getId());
        userVo.setEmail(vo.getEmail());
        List<SysUserDto> user = sysUserService.uniqueUser(userVo);
        if (user.size() > 0){
            return false;
        }
        return true;
    }

    /**
     * 用户的唯一性检验（手机号）
     * @param vo
     * @return
     */
    private Boolean uniqueUserPhone(SysUserVo vo){
        SysUserVo userVo =new SysUserVo();
        userVo.setId(vo.getId());
        userVo.setCellPhone(vo.getCellPhone());
        List<SysUserDto> user = sysUserService.uniqueUser(userVo);
        if (user.size() > 0){
            return false;
        }
        return true;
    }

}
